package com.open.capacity.paper.service.impl;

import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.open.capacity.common.exception.service.ServiceException;
import com.open.capacity.common.model.Option;
import com.open.capacity.common.model.QuestionOption;
import com.open.capacity.common.web.PageResult;
import com.open.capacity.common.web.Result;
import com.open.capacity.paper.dao.OptionDao;
import com.open.capacity.paper.dao.QuesionOptionDao;
import com.open.capacity.paper.service.OptionService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author liangd
 * @since 2021-01-29 17:24
 */
@Service
@Slf4j
public class OptionServiceImpl extends ServiceImpl<OptionDao, Option> implements OptionService {

    @Autowired
    private OptionDao optionDao;

    @Autowired
    private QuesionOptionDao quesionOptionDao;

    @Override
    public PageResult<Option> getOptions(Map<String, Object> params) throws ServiceException {
        try {
            if (MapUtils.getInteger(params, "page") != null && MapUtils.getInteger(params, "limit") != null) {
                PageHelper.startPage(MapUtils.getInteger(params, "page"), MapUtils.getInteger(params, "limit"), true);
            }
            List<Option> list = optionDao.findList(params);
            PageInfo<Option> pageInfo = new PageInfo<>(list);
            return PageResult.<Option>builder().code(0).count(pageInfo.getTotal()).data(pageInfo.getList()).build();
        } catch (Exception e) {
            throw new ServiceException(e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result delete(Integer id) throws ServiceException {
        try {
            List<QuestionOption> list = new LambdaQueryChainWrapper<>(quesionOptionDao).eq(QuestionOption::getOptnid, id).list();
            if (list.size() > 0) {
                return Result.failed("该选项与问题已关联，请先移除关系，在进行操作！");
            }
            optionDao.deleteOption(id);
            return Result.succeed("操作成功");
        } catch (Exception e) {
            throw new ServiceException(e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result updateOption(Option option) throws ServiceException {
        try {
            option.setUpdtim(new Date());
            optionDao.updateOption(option);
            return Result.succeed("更新成功");
        } catch (Exception e) {
            throw new ServiceException(e);
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result saveOption(Option option) throws ServiceException {
        try {
            option.setCretim(new Date());
            option.setStatus(1);
            optionDao.insertOption(option);
            return Result.succeed("保存成功");
        } catch (Exception e) {
            log.info(e.getMessage());
            throw new ServiceException(e);
        }
    }

    @Override
    public Result getOptionsByQuestionId(Integer quesid) throws ServiceException {
        try {
            List<Map<String,Object>> optionTrees = new ArrayList<>();
            Set<Integer> quesids = new HashSet<>();
            quesids.add(quesid);
            //查询当前问题已有选项
            Set<Option> quesOptions= optionDao.findOptionsByQuesIds(quesids);
            List<Option> allOptions = optionDao.findList(null);
            //选项数据
            Map<Integer, Option> collect = quesOptions.stream().collect(Collectors.toMap(Option::getOptnid, Option -> Option));
            for (Option option:allOptions) {
                Map<String,Object> optionTree = new HashMap<>();
                optionTree.put("id",option.getOptnid());
                optionTree.put("name",option.getOpname());
                optionTree.put("open",true);
                optionTree.put("checked",false);
                if (collect.get(option.getOptnid())!=null){
                    optionTree.put("checked",true);
                }
                optionTrees.add(optionTree);
            }
            return Result.succeed(optionTrees,"");
        } catch (Exception e) {
            log.info(e.getMessage());
            throw new ServiceException(e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result addOptions(Integer quesid, Set<Integer> optionIds) throws ServiceException {
        try {
            List<QuestionOption> questionOptions = new LambdaQueryChainWrapper<>(quesionOptionDao).eq(QuestionOption::getQuesid, quesid).list();
            Set<Integer> collect = questionOptions.stream().map(QuestionOption::getOptnid).collect(Collectors.toSet());
            //比较集合元素
            Collection<Integer> subtract = CollectionUtils.subtract(optionIds, collect);
            Set<Integer> set = new HashSet<>(subtract);
            if (set.size()!=0){
                List<QuestionOption> questionOptionList=new ArrayList<>();
                for (Integer i:set){
                    QuestionOption questionOption = QuestionOption.builder().optnid(i).quesid(quesid).build();
                    questionOptionList.add(questionOption);
                }
                quesionOptionDao.insertBatch(questionOptionList);
            }
            Collection<Integer> subtract1 = CollectionUtils.subtract(collect, optionIds);
            Set<Integer> set1 = new HashSet<>(subtract1);
            if (set1.size()!=0){
                quesionOptionDao.deleteBatchByIds(quesid,set1);
            }
            return Result.succeed("操作成功");
        }catch (Exception e){
            log.info(e.getMessage());
            throw new ServiceException(e);
        }
    }

}
